<template>
  <main v-if="isShow" class="scene-tree-node">
    <div class="_vti-line"></div>
    <div v-if="isSingle" class="_single-vt-line"></div>
    <span
      class="g-relative g-one-line node-item"
      @click="clickNode(nodeData?.id)"
      @dblclick="dblclickNode"
    >
      <span
        v-if="nodeData?.children && nodeData.children.length"
        class="g-pointer"
        @click="handleToggleExpand"
      >
        <div class="_rect">
          <div class="_rect-1"></div>
          <div v-if="!nodeData.expand" class="_rect-2"></div>
        </div>
      </span>
      <span v-else class="_hr-line _empty-line"></span>
      <span class="_hr-line" />
      <img
        v-if="nodeData?.type"
        :src="nodeData.icon"
        alt="icon"
        class="_tree-node-icon"
        style="height: 16px; width: 16px"
      />
      <span class="node-name" :class="{ _selected: nodeData?.isSelected }">
        {{ nodeData?.name }}
      </span>
      <span v-if="stateLabel" :style="renderStyle"> ({{ stateLabel }})</span>
      <span class="node-des">{{ nodeData?.des }}</span>
    </span>
    <div
      v-show="nodeData?.children && nodeData.expand"
      class="_sub-node-wrapper"
    >
      <SceneNode
        v-for="item in nodeData?.children"
        :key="item.id"
        :nodeData="item"
        :is-single="nodeData?.children.length === 1"
      />
    </div>
  </main>
</template>
<script lang="ts" setup>
import { controller } from "@/engine/Controller";
import { SceneState, SceneStateColor, SceneStateLabel } from "@/engine/_";
import { HiddenStatus } from "@/engine/types/Controller";
import { rmi } from "@/util/RMI";
import { computed } from "vue";

const props = defineProps({
  nodeData: Object,
  isSingle: Boolean,
});

const isShow = computed(() => {
  if (props.nodeData?.type.includes("constraintBlock")) return false;
  if (props.nodeData?.modelVo.hiddenStatus === HiddenStatus.HIDDEN_IN_ENCAP)
    return false;
  return true;
});

const renderStyle = computed(() => {
  const state = props.nodeData?.state as SceneState;
  return {
    color: SceneStateColor[state],
  };
});

const stateLabel = computed(() => {
  const state = props.nodeData?.state as SceneState;
  return SceneStateLabel[state];
});

const handleToggleExpand = () => {
  if (props.nodeData) props.nodeData.expand = !props.nodeData.expand;
};

const clickNode = (sceneId: string) => {
  console.log(props.nodeData);
  controller.sceneService.sceneChange(sceneId);
  controller.toolbarService.signalValue = "";
};

const dblclickNode = async () => {
  const nodeData = props.nodeData;
  if (nodeData) {
    const model = nodeData.modelVo;

    // 双击交互、活动、状态机时，打开对应的行为图（如果有）
    if (
      ["Interaction", "Activity", "StateMachine"].indexOf(model.metaclass) > -1
    ) {
      // 查询子类行为图(活动图，行为图，状态机图)
      const children = await controller.modelApi.getChildren(
        controller.projectId,
        model.id
      );
      if (children.length) {
        const targetDiagram = children.find(
          (it: any) =>
            [
              "SysMLDI::SysMLInteractionDiagram",
              "SysMLDI::SysMLActivityDiagram",
              "SysMLDI::SysMLStateMachineDiagram",
            ].indexOf(it.baseSt) > -1
        );
        if (targetDiagram) {
          // 打开图
          await rmi.invokeAction("openDiagram", [targetDiagram]);
        }
      }
    }
  }
};
</script>
<style lang="scss">
.scene-tree-node {
  position: relative;
  .node-name {
    margin-left: 6px;
    display: inline-block;
    &._selected {
      color: white;
      background: #3483b8;
    }
  }
  .node-item {
    cursor: pointer;
  }
  .node-des {
    color: rgba(0, 0, 0, 0.65);
  }
  ._sub-node-wrapper {
    margin-left: 27px;
    position: relative;
  }
  &:last-of-type {
    & > ._vti-line {
      display: none;
    }
  }
  & > ._vti-line {
    height: calc(100% + 7px);
    border-left: 1px solid black;
    position: absolute;
    top: 3px;
    left: 5px;
  }
  & > ._single-vt-line {
    height: 12px;
    border-left: 1px solid black;
    position: absolute;
    top: -2px;
    left: 4px;
  }
  ._hr-line {
    display: inline-block;
    width: 10px;
    height: 1px;
    border-top: 1px solid black;
    position: relative;
    top: -1px;
    &._empty-line {
      margin-left: 5px;
      width: 5px;
    }
  }
  ._rect {
    width: 11px;
    height: 11px;
    box-sizing: border-box;
    border: 1px solid black;
    position: relative;
    display: inline-block;
    background: white;
    top: 2px;
    ._rect-1 {
      position: absolute;
      width: 5px;
      border-top: 1px solid black;
      left: 2px;
      top: 4px;
    }
    ._rect-2 {
      position: absolute;
      height: 5px;
      border-left: 1px solid black;
      left: 4px;
      top: 2px;
    }
  }
}
</style>
